package com.platform.common.aspectj;

import cn.hutool.core.date.DateUtil;
import com.platform.common.shiro.ShiroUtils;
import com.platform.common.utils.IpUtils;
import com.platform.common.utils.ServletUtils;
import com.platform.modules.sys.domain.SysLog;
import com.platform.modules.sys.service.SysLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Configuration
@Slf4j
public class SysLogAspect {

    @Resource
    private SysLogService sysLogService;

    /**
     * Controller层切点
     */
    @Pointcut("@annotation(SysLogRepeat)")
    public void controllerAspect() {
    }

    /**
     * 前置通知  用于拦截Controller层记录用户的操作
     */
    @Before("controllerAspect()")
    public void doBefore(JoinPoint joinPoint) {
        SysLogRepeat sysLogRepeat = initSysLogRepeat(joinPoint);
        String username = null;
        if (!sysLogRepeat.needLogin()) {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            username = request.getParameter("username");
        } else {
            // 登录用户
            username = ShiroUtils.getUser().getUsername();
        }
        String methodName = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName();
        String requestIp = IpUtils.getIpAddr(ServletUtils.getRequest());

        // 组装对象
        SysLog sysLog = new SysLog();
        sysLog.setUsername(username);
        sysLog.setModuleType(sysLogRepeat.moduleType().getCode());
        sysLog.setMethodName(methodName);
        sysLog.setRequestIp(requestIp);
        sysLog.setRemark(sysLogRepeat.remark());
        sysLog.setCreateTime(DateUtil.date());
        //保存数据库
        sysLogService.add(sysLog);
    }

    /**
     * 获取 SysLogRepeat
     */
    private SysLogRepeat initSysLogRepeat(JoinPoint joinPoint) {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();//目标方法名
        Class targetClass = null;
        Object[] arguments = joinPoint.getArgs();
        try {
            targetClass = Class.forName(targetName);
        } catch (ClassNotFoundException e) {
            log.error("initSysLogRepeat出错：", e);
        }
        Method[] methods = targetClass.getMethods();
        for (Method method : methods) {
            Class[] clazzs = method.getParameterTypes();
            if (clazzs.length == arguments.length) {
                if (method.getName().equals(methodName)) {
                    return method.getAnnotation(SysLogRepeat.class);
                }
            }
        }
        return null;
    }
}
